package org.gdstash.file;

import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class DynamicByteArray
{
    static final int DEFAULT_SIZE = 10240;
    private final int size;
    private List<ByteArray> list;
    private ByteArray currArr;
    
    public DynamicByteArray() {
        this(10240);
    }
    
    public DynamicByteArray(final int size) {
        if (size <= 0) {
            throw new IllegalArgumentException();
        }
        this.size = size;
        this.clear();
    }
    
    public void append(final byte b) {
        if (this.currArr.isFull()) {
            this.currArr = new ByteArray(this.size);
            this.list.add(this.currArr);
        }
        this.currArr.append(b);
    }
    
    public void clear() {
        this.list = new LinkedList<ByteArray>();
        this.currArr = new ByteArray(this.size);
        this.list.add(this.currArr);
    }
    
    public int length() {
        int len = 0;
        for (final ByteArray ba : this.list) {
            len += ba.getPosition();
        }
        return len;
    }
    
    @Override
    public String toString() {
        final int len = this.length();
        final byte[] arr = new byte[len];
        int idx = 0;
        for (final ByteArray ba : this.list) {
            final byte[] temp = ba.getByteArray();
            for (int pos = ba.getPosition(), i = 0; i < pos; ++i) {
                arr[idx] = temp[i];
                ++idx;
            }
        }
        final String s = new String(arr, StandardCharsets.UTF_8);
        return s;
    }
    
    private class ByteArray
    {
        private byte[] arr;
        private int pos;
        
        public ByteArray(final int size) {
            this.arr = new byte[size];
            this.pos = 0;
        }
        
        public byte[] getByteArray() {
            return this.arr;
        }
        
        public int getPosition() {
            return this.pos;
        }
        
        public boolean isFull() {
            return this.pos == this.arr.length;
        }
        
        public void append(final byte b) {
            this.arr[this.pos] = b;
            ++this.pos;
        }
    }
}
